package deviceservice.core;

import com.alibaba.fastjson.JSON;

import com.cetc.cloud.kmga.util.HttpUtil;
import com.cetc.cloud.kmga.util.SslUtil;
import com.google.common.base.CharMatcher;
import deviceservice.constants.Constants;
import deviceservice.entity.reponse.DevAddResp;
import deviceservice.entity.req.DevAddReq;
import deviceservice.entity.result.Result;
import deviceservice.exception.ManageException;
import deviceservice.token.AuthToken;
import deviceservice.utils.CryptoUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Jason on 2017/8/22.
 */
public class DevManager {
    private static final Log LOG = LogFactory.getLog(DevManager.class);
    public static Result addDevice(String flag,int devType,String username, String passwd, String sysAdd, String logIP, int heart, Object ... args){
        LOG.info("[server] addDevices begin.");
        long timestamp = System.currentTimeMillis();
        Result addDevResult = new Result();
        String postURL = sysAdd+"/add_device";
        String access_token;
        String deviceID;
        String token =AuthToken.getAddreqToken(timestamp,username, CryptoUtil.hash(passwd),postURL);
        LOG.debug("[server] addDevice first token is "+token);
        DevAddReq devAddReq = new DevAddReq();
        devAddReq.setTimestamp(timestamp);
        devAddReq.setUser(username);
        devAddReq.setToken(token);
        String postData = JSON.toJSONString(devAddReq);
        Boolean result=false;
       LOG.debug("[server] the add device first postURL is "+postURL);
        try {
            SslUtil.ignoreSsl();
        } catch (Exception e) {
            e.printStackTrace();
        }
        HttpUtil httpclient = new HttpUtil(postURL);
        if(flag.contentEquals(httpclient.APPLICATION_FORM_URLENCODED)){
            Map<String,String> paraMap = new HashMap<>();
            paraMap.put("timestamp",String.valueOf(timestamp));
            paraMap.put("user",username);
            paraMap.put("token",token);
            result = httpclient.sendPostRequest(paraMap,httpclient.APPLICATION_FORM_URLENCODED);
        }
        else{
         result = httpclient.sendPostRequest(postData,httpclient.APPLICATION_JSON);
        }//发送加入请求
             LOG.debug("[server] the POSTURL is "+ postURL);
        if (result){// 请求发送成功
            System.out.print(System.currentTimeMillis()+"***************");
            LOG.info("[server] post add device request success");
            DevAddResp devAddResp =JSON.parseObject(httpclient.getResponseString(),DevAddResp.class);
            if (devAddResp.getResult()==100){//设备端验证成功
                LOG.info("[server] the authentication of client about addDevice is  successful");
              String resToken = AuthToken.getAddresToken(devAddResp.getResult(),timestamp, devAddResp.getTimestamp(),username,CryptoUtil.hash(passwd));

                if(resToken.contentEquals(devAddResp.getToken())){//服务端验证成功，开始生成access_token，并发送devId。
                    LOG.info("[server] the authentication of server success ,begin to generate accesston and send devID");
                  access_token = AuthToken.getAccessToken(timestamp, devAddResp.getTimestamp(),username,CryptoUtil.hash(passwd));

                    deviceID = AuthToken.getdevID(timestamp,sysAdd).substring(2,11).replace("/","").replace("&","").replace("?","");
                    deviceID=CharMatcher.anyOf("+=/").removeFrom(deviceID);
                    long ts = timestamp+1;

                    String reqToken = AuthToken.getDevReqToken(ts,access_token,deviceID,heart,logIP);
                    LOG.debug("timestamp :"+ts+"accesstoke:"+access_token+"deviceID"+deviceID+"heart"+heart+"logIP"+logIP);
                    postURL = sysAdd+"/add_ID";
                    LOG.debug("[server] the add deviceID postURL is "+postURL);
                    //construction of send device id request
                    DevAddReq devAddReq1 =new DevAddReq();
                    devAddReq1.setTimestamp(ts);
                    devAddReq1.setDevID(deviceID);
                    devAddReq1.setHeart(heart);
                    devAddReq1.setLogIP(logIP);
                    devAddReq1.setToken(reqToken);
                   devAddReq1.setLogTypeMap((Map)Constants.devAndLogTypeMap.get(devType));

                    if(args.length==2){
                        LOG.info("[server] add the logUser and logPass");

                        devAddReq1.setLogUser(args[0].toString());
                        devAddReq1.setLogPass(CryptoUtil.aesEncrypt(args[1].toString(),CryptoUtil.hash(access_token)));

                    }
                    try {
                        SslUtil.ignoreSsl();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    HttpUtil httpUtil = new HttpUtil(postURL);
                    if(flag.contentEquals(httpUtil.APPLICATION_FORM_URLENCODED)){
                        String dataType = JSON.toJSONString(Constants.devAndLogTypeMap.get(devType));

                        Map<String,String> paraMap = new HashMap<>();
                        paraMap.put("timestamp",String.valueOf(ts));
                        paraMap.put("devID",deviceID);
                        paraMap.put("heart",String.valueOf(heart));
                        paraMap.put("logIP",logIP);
                        paraMap.put("token",reqToken);
                        paraMap.put("logTypeMap",dataType);
                        if(args.length==2){
                            LOG.info("[server] add the logUser and logPass");
                            paraMap.put("logUser",args[0].toString());
                            paraMap.put("logPass",CryptoUtil.aesEncrypt(args[1].toString(),CryptoUtil.hash(access_token)));
                        }
                        result = httpUtil.sendPostRequest(paraMap,httpUtil.APPLICATION_FORM_URLENCODED);
                    }
                    else{
                    String data = JSON.toJSONString(devAddReq1);
                    result = httpUtil.sendPostRequest(data,httpUtil.APPLICATION_JSON);
                    }
                    if(result){
                        System.out.print(System.currentTimeMillis()+"***************");
                        LOG.info("[server] send devID request success");
                        DevAddResp devAddResp1 = JSON.parseObject(httpUtil.getResponseString(),DevAddResp.class);
                        if(devAddResp1.getResult()==100){//客户端验证成功，并且成功接收devID
                            LOG.info("[server] the authentication of client about devID is  successful");
                            addDevResult.setResult(true);
                            addDevResult.setAccessToken(access_token);
                            addDevResult.setDevID(deviceID);
                        }
                        else{
                            addDevResult.setResult(false);
                          LOG.error("[server] the authentication of client about devID is  FAILED : "+"[");
                        }
                    }
                    else{
                    addDevResult.setResult(false);
                   LOG.error("[server] send devID request FAILED");
                    }


                }
                else{
                    addDevResult.setResult(false);
                    LOG.error("[server] the authentication of server faild,stop to generate accessToken ");
                }
            }
            else{
                addDevResult.setResult(false);

                LOG.error("[server] the authentication of client faild");
            }
         }
        else
             {
            addDevResult.setResult(false);
            LOG.error("[server] POST first url failed");

                      }

        addDevResult.setUser(username);
        addDevResult.setSysAdd(sysAdd);
       return addDevResult;
    }

    public  static void logIn (String userType,String devID,String accessToken,String sysAdd){
        long timestamp = System.currentTimeMillis();
        String token = AuthToken.getLoginToken(accessToken,timestamp,devID);
        String postUrl = sysAdd+"/single_sign_on";
        DevAddReq logInReq = new DevAddReq();
        logInReq.setUsertype(userType);
        logInReq.setToken(token);
        logInReq.setTimestamp(timestamp);
        try {
            SslUtil.ignoreSsl();
        } catch (Exception e) {
            e.printStackTrace();
        }
        HttpUtil httpclient = new HttpUtil(postUrl);
        String postData = JSON.toJSONString(logInReq);
        Boolean result = httpclient.sendPostRequest(postData,httpclient.APPLICATION_JSON);//发送请求

    }
    public static List<Object> query(String flag,String sysAdd, String accesstoken, String devID, String query)throws Exception{
        long timestamp = System.currentTimeMillis();
        List resultList = new ArrayList<>();
        String token =AuthToken.getQueryToken(accesstoken,timestamp,query,devID);
        String postUrl = sysAdd+"/manage/query";
        DevAddReq queryReq = new DevAddReq();
        queryReq.setToken(token);
        queryReq.setTimestamp(timestamp);
        queryReq.setQuery(query);
        queryReq.setDevID(devID);
        try {
            SslUtil.ignoreSsl();
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception();
        }
        HttpUtil httpclient = new HttpUtil(postUrl);
        String postData = JSON.toJSONString(queryReq);
        Boolean result=false;
        if(flag.contentEquals(httpclient.APPLICATION_FORM_URLENCODED)){
            Map<String,String> paraMap = new HashMap<>();
            paraMap.put("token",token);
            paraMap.put("timestamp",String.valueOf(timestamp));
            paraMap.put("query",query);
            paraMap.put("devID",devID);
            result = httpclient.sendPostRequest(paraMap,httpclient.APPLICATION_FORM_URLENCODED);
        }
        else {
         result = httpclient.sendPostRequest(postData,httpclient.APPLICATION_JSON);}//发送请求
        if(result){
            DevAddResp devAddResp =JSON.parseObject(httpclient.getResponseString(),DevAddResp.class);
            if(devAddResp.getResult()!=100){
                throw  new ManageException("the Device : "+devID+"had a exception."+devAddResp.getMessage());
            }
            else {
                String queryresultTokentoken = AuthToken.getQueryResultToken(accesstoken, timestamp + 1, devID, CryptoUtil.hash(new String(devAddResp.getData().get(devAddResp.getData().size() - 1).getAuditObjName().getBytes("UTF-8"))), devAddResp.getResult());
                if (queryresultTokentoken.equals(devAddResp.getToken())) {
                    if (devAddResp.getResult() == 100)
                        resultList = devAddResp.getData();
                }
            }


        }
        return resultList;
    }
    public static boolean fill(String flag,String sysAdd,String accesstoken,String devID,String command)throws Exception {
        long timestamp = System.currentTimeMillis();
        String token = AuthToken.getFillToken(accesstoken, timestamp, command, devID);
        String postUrl = sysAdd + "/manage/fill";
        DevAddReq fillReq = new DevAddReq();
        fillReq.setToken(token);
        fillReq.setTimestamp(timestamp);
        fillReq.setCommand(command);
        fillReq.setDevID(devID);
        try {
            SslUtil.ignoreSsl();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Boolean result=false;
        HttpUtil httpclient = new HttpUtil(postUrl);
        if(flag.contentEquals(httpclient.APPLICATION_FORM_URLENCODED)){
            Map<String,String> paraMap = new HashMap<>();
            paraMap.put("token",token);
            paraMap.put("timestamp",String.valueOf(timestamp));
            System.out.println("时间：" + timestamp);
            paraMap.put("command",command);
            paraMap.put("devID",devID);
            result = httpclient.sendPostRequest(paraMap,httpclient.APPLICATION_FORM_URLENCODED);
        }
        else{
        String postData = JSON.toJSONString(fillReq);
         result = httpclient.sendPostRequest(postData, httpclient.APPLICATION_JSON);}//发送请求
        if (result) {//发送成功
            DevAddResp devAddResp = JSON.parseObject(httpclient.getResponseString(), DevAddResp.class);
            if(devAddResp.getResult()!=100){

                throw  new ManageException("the Device : "+devID+"had a exception."+devAddResp.getMessage());

            }
            else {
            String fillresultTokentoken = AuthToken.getResultToken(accesstoken, timestamp+1, devID, devAddResp.getResult());
            if (fillresultTokentoken.contentEquals(devAddResp.getToken()))//验证成功
            {
                if (devAddResp.getResult() == 100)
                    return true;
                else
                    return false;
            } else
                return false;
            }
        } else
            return false;

    }

}
